home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mint110s / dossig.c < prev    next >
C/C++ Source or Header  |  1993-08-16  |  5KB  |  213 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith.
  3. All rights reserved.
  4. */
  5.  
  6. /* dossig.c:: dos signal handling routines */
  7.  
  8. #include "mint.h"
  9.  
  10. /*
  11.  * send a signal to another process. If pid > 0, send the signal just to
  12.  * that process. If pid < 0, send the signal to all processes whose process
  13.  * group is -pid. If pid == 0, send the signal to all processes with the
  14.  * same process group id.
  15.  *
  16.  * note: post_sig just posts the signal to the process.
  17.  */
  18.  
  19. long ARGS_ON_STACK
  20. p_kill(pid, sig)
  21.     int pid, sig;
  22. {
  23.     PROC *p;
  24.  
  25.     TRACE(("Pkill(%d, %d)", pid, sig));
  26.     if (sig < 0 || sig >= NSIG) {
  27.         DEBUG(("Pkill: signal out of range"));
  28.         return ERANGE;
  29.     }
  30.  
  31.     if (pid < 0)
  32.         return killgroup(-pid, sig);
  33.     else if (pid == 0)
  34.         return killgroup(curproc->pgrp, sig);
  35.     else {
  36.         p = pid2proc(pid);
  37.         if (p == 0 || p->wait_q == ZOMBIE_Q || p->wait_q == TSR_Q) {
  38.             DEBUG(("Pkill: pid %d not found", pid));
  39.             return EFILNF;
  40.         }
  41.         if (curproc->euid && curproc->ruid != p->ruid) {
  42.             DEBUG(("Pkill: wrong user"));
  43.             return EACCDN;
  44.         }
  45.  
  46. /* if the user sends signal 0, don't deliver it -- for users, signal
  47.  * 0 is a null signal used to test the existence of a process
  48.  */
  49.         if (sig != 0)
  50.             post_sig(p, sig);
  51.     }
  52.  
  53.     check_sigs();
  54.     TRACE(("Pkill: returning OK"));
  55.     return 0;
  56. }
  57.  
  58. /*
  59.  * set a user-specified signal handler, POSIX.1 style
  60.  * "oact", if non-null, gets the old signal handling
  61.  * behaviour; "act", if non-null, specifies new
  62.  * behaviour
  63.  */
  64.  
  65. long ARGS_ON_STACK
  66. p_sigaction(sig, act, oact)
  67.     int sig;
  68.     const struct sigaction *act;
  69.     struct sigaction *oact;
  70. {
  71.     TRACE(("Psigaction(%d)", sig));
  72.     if (sig < 1 || sig >= NSIG)
  73.         return ERANGE;
  74.     if (act && (sig == SIGKILL || sig == SIGSTOP))
  75.         return EACCDN;
  76.     if (oact) {
  77.         oact->sa_handler = curproc->sighandle[sig];
  78.         oact->sa_mask = curproc->sigextra[sig];
  79.         oact->sa_flags = curproc->sigflags[sig] & SAUSER;
  80.     }
  81.     if (act) {
  82.         ushort flags;
  83.  
  84.         curproc->sighandle[sig] = act->sa_handler;
  85.         curproc->sigextra[sig] = act->sa_mask & ~UNMASKABLE;
  86.  
  87. /* only the flags in SAUSER can be changed by the user */
  88.         flags = curproc->sigflags[sig] & ~SAUSER;
  89.         flags |= act->sa_flags & SAUSER;
  90.         curproc->sigflags[sig] = flags;
  91.  
  92. /* various special things that should happen */
  93.         if (act->sa_handler == SIG_IGN) {
  94.             /* discard pending signals */
  95.             curproc->sigpending &= ~(1L<<sig);
  96.         }
  97.  
  98. /* I dunno if this is right, but bash seems to expect it */
  99.          curproc->sigmask &= ~(1L<<sig);
  100.     }
  101.     return 0;
  102. }
  103.  
  104. /*
  105.  * set a user-specified signal handler
  106.  */
  107.  
  108. long ARGS_ON_STACK
  109. p_signal(sig, handler)
  110.     int sig;
  111.     long handler;
  112. {
  113.     long oldhandle;
  114.  
  115.     TRACE(("Psignal(%d, %lx)", sig, handler));
  116.     if (sig < 1 || sig >= NSIG)
  117.         return ERANGE;
  118.     if (sig == SIGKILL || sig == SIGSTOP)
  119.         return EACCDN;
  120.     oldhandle = curproc->sighandle[sig];
  121.     curproc->sighandle[sig] = handler;
  122.     curproc->sigextra[sig] = 0;
  123.     curproc->sigflags[sig] = 0;
  124.  
  125. /* various special things that should happen */
  126.     if (handler == SIG_IGN) {
  127.         /* discard pending signals */
  128.         curproc->sigpending &= ~(1L<<sig);
  129.     }
  130.  
  131. /* I dunno if this is right, but bash seems to expect it */
  132.     curproc->sigmask &= ~(1L<<sig);
  133.  
  134.     return oldhandle;
  135. }
  136.  
  137. /*
  138.  * block some signals. Returns the old signal mask.
  139.  */
  140.  
  141. long ARGS_ON_STACK
  142. p_sigblock(mask)
  143.     ulong mask;
  144. {
  145.     ulong oldmask;
  146.  
  147.     TRACE(("Psigblock(%lx)",mask));
  148. /* some signals (e.g. SIGKILL) can't be masked */
  149.     mask &= ~(UNMASKABLE);
  150.     oldmask = curproc->sigmask;
  151.     curproc->sigmask |= mask;
  152.     return oldmask;
  153. }
  154.  
  155. /*
  156.  * set the signals that we're blocking. Some signals (e.g. SIGKILL)
  157.  * can't be masked.
  158.  * Returns the old mask.
  159.  */
  160.  
  161. long ARGS_ON_STACK
  162. p_sigsetmask(mask)
  163.     ulong mask;
  164. {
  165.     ulong oldmask;
  166.  
  167.     TRACE(("Psigsetmask(%lx)",mask));
  168.     oldmask = curproc->sigmask;
  169.     curproc->sigmask = mask & ~(UNMASKABLE);
  170.     check_sigs();    /* maybe we unmasked something */
  171.     return oldmask;
  172. }
  173.  
  174. /*
  175.  * p_sigpending: return which signals are pending delivery
  176.  */
  177.  
  178. long ARGS_ON_STACK
  179. p_sigpending()
  180. {
  181.     TRACE(("Psigpending()"));
  182.     check_sigs();    /* clear out any that are going to be delivered soon */
  183.  
  184. /* note that signal #0 is used internally, so we don't tell the process
  185.  * about it
  186.  */
  187.     return curproc->sigpending & ~1L;
  188. }
  189.  
  190. /*
  191.  * p_sigpause: atomically set the signals that we're blocking, then pause.
  192.  * Some signals (e.g. SIGKILL) can't be masked.
  193.  */
  194.  
  195. long ARGS_ON_STACK
  196. p_sigpause(mask)
  197.     ulong mask;
  198. {
  199.     ulong oldmask;
  200.  
  201.     TRACE(("Psigpause(%lx)", mask));
  202.     oldmask = curproc->sigmask;
  203.     curproc->sigmask = mask & ~(UNMASKABLE);
  204.     if (curproc->sigpending & ~(curproc->sigmask))
  205.         check_sigs();    /* a signal is immediately pending */
  206.     else
  207.         sleep(IO_Q, -1L);
  208.     curproc->sigmask = oldmask;
  209.     check_sigs();    /* maybe we unmasked something */
  210.     TRACE(("Psigpause: returning OK"));
  211.     return 0;
  212. }
  213.